#ifndef SOLVER_HPP
#define SOLVER_HPP

#include "Array.hpp"
#include <math.h>
#include <iostream>
#include <iomanip>
#include "Debug.hpp"
#define PI 3.14159265

class Solver
{
private:
   typedef std::vector<Array> Grids;

public:
    //constructor
    explicit Solver(size_t nLevels):levels_(nLevels)
    {
        for(size_t l=0; l<levels_; ++l)
        {
            x_.push_back(Array());
            f_.push_back(Array());
            r_.push_back(Array());
        }
        for(size_t l=0; l<levels_; ++l)
        {
            x_[l].resize(l);
            f_[l].resize(l);
            r_[l].resize(l);
        }
    }
    //destructor
    ~Solver() {}
    
    void Solve(Array &x, const Array &f, size_t cycles, size_t pre, size_t post);
    void mgSolve(Array& x, const Array& f, size_t cycles, size_t pre_iter, size_t post_iter);

private:
    size_t levels_;
    Grids x_;
    Grids f_;
    Grids r_;

public:
    void smoothGS(Array &x, const Array &f, size_t iter);
    void smoothGSRB(Array &x, const Array &f, size_t iter);
    void calcResidual (const Array &x, const Array &f, Array &r);
    void restrict(Array &r, Array &f);
    void prolongateAndCorrect(const Array &e, Array &x);
};

#endif //SOLVER_HPP

